package cn.mw.cmdb.template.strategy.handler;

import cn.mw.cmdb.exception.ZabbixResultException;
import cn.mw.cmdb.template.constant.MwTemplateConfigurationConstant;
import cn.mw.cmdb.template.entity.TriggerDto;
import cn.mw.cmdb.template.entity.convert.MwTriggerConvertDto;
import cn.mw.cmdb.template.enums.TemplateDetailEnum;
import cn.mw.cmdb.template.enums.TriggerFunctionsDto;
import cn.mw.cmdb.template.param.MonitorItemParam;
import cn.mw.cmdb.template.param.MwTemplateConfigurationParam;
import cn.mw.cmdb.template.param.TriggerParam;
import cn.mw.cmdb.template.strategy.TemplateDetailHandler;
import cn.mw.cmdb.template.utils.TemplateSortUtil;
import cn.mw.microMonitorCommon.constants.ZabbixApiConstants;
import cn.mw.microMonitorCommon.constants.ZabbixMethodConstants;
import cn.mw.microMonitorCommon.entity.zabbix.MWZabbixAPIResult;
import cn.mw.microMonitorCommon.util.ListMapObjUtils;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description 监控项处理
 */
@Service
@Slf4j
public class TriggerHandler extends TemplateDetailHandler {

    private final String OP_DATA = "opdata";
    private final String TRIGGER_IDS = "triggerids";
    private final String dependencies = "dependencies";

    @Override
    public TemplateDetailEnum handlerType() {
        return TemplateDetailEnum.TRIGGERS;
    }


    @Override
    public Object getData(MwTemplateConfigurationParam param) {
        List<TriggerDto> triggerDtos = new ArrayList<>();
        //获取监控项的触发器信息
        Map zabbixTriggerParam = new HashMap();
        zabbixTriggerParam.put(MwTemplateConfigurationConstant.OUTPUT,Arrays.asList(TRIGGER_ID,description,expression,priority,status,OP_DATA));
        if(StringUtils.isNotEmpty(param.getTemplateId())){
            zabbixTriggerParam.put(MwTemplateConfigurationConstant.TEMPLATE_IDS,param.getTemplateId());
        }
        if(StringUtils.isNotEmpty(param.getHostId())){
            zabbixTriggerParam.put(HOST_IDS,param.getHostId());
        }
        zabbixTriggerParam.put(MwTemplateConfigurationConstant.selectFunctions,MwTemplateConfigurationConstant.EXTEND);
        MWZabbixAPIResult triggerResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TRIGGER_GET, zabbixTriggerParam);
        if(triggerResult == null || triggerResult.isFail()){
            throw new ZabbixResultException(String.valueOf(triggerResult.getData()));
        }
        List<MwTriggerConvertDto> triggerConvertDtos = JSONArray.parseArray(String.valueOf(triggerResult.getData()), MwTriggerConvertDto.class);
        if(CollectionUtils.isEmpty(triggerConvertDtos)){
            return triggerDtos;
        }
        //翻译表达式
        translateExpression(triggerConvertDtos,param);
        for (MwTriggerConvertDto triggerConvertDto : triggerConvertDtos) {
            TriggerDto triggerDto = new TriggerDto();
            triggerDto.extractFrom(triggerConvertDto);
            triggerDtos.add(triggerDto);
        }
        if(CollectionUtils.isNotEmpty(triggerDtos) && StringUtils.isNotEmpty(param.getDetailName())){
            triggerDtos = triggerDtos.stream().filter(item->item.getDescription().contains(param.getDetailName())).collect(Collectors.toList());
        }
        List realData = TemplateSortUtil.templateSortList(triggerDtos,param,param.getQuery());
        if(param.getPageNum() == null || param.getPageSize() == null){
            return realData;
        }
        Page page = pageHandler(realData, param.getPageNum(), param.getPageSize());
        return page;
    }


    private void translateExpression(List<MwTriggerConvertDto> triggerConvertDtos,MwTemplateConfigurationParam param){
        //获取itemid
        List<String> itemIds = new ArrayList<>();
        for (MwTriggerConvertDto triggerConvertDto : triggerConvertDtos) {
            List<TriggerFunctionsDto> functions = triggerConvertDto.getFunctions();
            if(CollectionUtils.isEmpty(functions)){continue;}
            itemIds.addAll(functions.stream().map(s->s.getItemid()).collect(Collectors.toList()));
        }
        if(CollectionUtils.isEmpty(itemIds)){return;}
        String name = null;
        if(StringUtils.isNotEmpty(param.getTemplateId())){
            name =  getTemplateName(param);
        }
        if(StringUtils.isNotEmpty(param.getHostId())){
            name =  getHostName(param);
        }
        param.setTemplateName(name);
        //监控项的键值
        Map zabbixParam = new HashMap();
        zabbixParam.put(MwTemplateConfigurationConstant.ITEM_IDS,itemIds);
        zabbixParam.put(MwTemplateConfigurationConstant.OUTPUT,Arrays.asList(MwTemplateConfigurationConstant.ITEM_ID,key_,MwTemplateConfigurationConstant.NAME));
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.ITEM_GET, zabbixParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        List<MonitorItemParam> monitorItemParams = JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MonitorItemParam.class);
        if(CollectionUtils.isEmpty(monitorItemParams)){return;}
        Map<String, String> itemMap = monitorItemParams.stream().collect(Collectors.toMap(s -> s.getItemid(), s -> s.getKey_()));
        for (MwTriggerConvertDto triggerConvertDto : triggerConvertDtos) {
            String triggerExpression = triggerConvertDto.getExpression();
            List<TriggerFunctionsDto> functions = triggerConvertDto.getFunctions();
            if(CollectionUtils.isEmpty(functions)){continue;}
            for (TriggerFunctionsDto function : functions) {
                String functionId = function.getFunctionid();
                if(triggerExpression.contains(functionId)){
                    String itemKey = itemMap.get(function.getItemid());
                    triggerExpression = assembleExpression(triggerExpression,param.getTemplateName(), itemKey, function);
                }
            }
            triggerConvertDto.setExpression(triggerExpression);
        }
    }

    @Override
    public Object createData(MwTemplateConfigurationParam param) {
        Object detailData = param.getDetailData();
        TriggerParam triggerParam = JSONObject.parseObject(JSONObject.toJSONString(detailData), TriggerParam.class);
        Map zabbixParam = ListMapObjUtils.beanToMap(triggerParam);
        delMapNullValue(zabbixParam);
        handlerDependent(zabbixParam);
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TRIGGER_CREATE, zabbixParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        return null;
    }

    private void handlerDependent(Map zabbixParam){
        if(zabbixParam.containsKey(dependencies)){
            List<String> ids = (List<String>) zabbixParam.get(dependencies);
            List<Map> listMaps = new ArrayList<>();
            for (String id : ids) {
                Map map = new HashMap();
                map.put(TRIGGER_ID,id);
                listMaps.add(map);
            }
            zabbixParam.put(dependencies,listMaps);
        }
    }


    @Override
    public Object updateData(MwTemplateConfigurationParam param) {
        Object detailData = param.getDetailData();
        TriggerParam triggerParam = JSONObject.parseObject(JSONObject.toJSONString(detailData), TriggerParam.class);
        Map zabbixParam = ListMapObjUtils.beanToMap(triggerParam);
        delMapNullValue(zabbixParam);
        handlerDependent(zabbixParam);
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TRIGGER_UPDATE, zabbixParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        return null;
    }

    @Override
    public Object deleteData(MwTemplateConfigurationParam param) {
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TRIGGER_DELETE, param.getDetailDeleteIds());
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        return null;
    }

    @Override
    public Object selectDataById(MwTemplateConfigurationParam param) {
        Map zabbixParam = new HashMap();
        zabbixParam.put(TRIGGER_IDS,Arrays.asList(param.getDetailId()));
        zabbixParam.put(MwTemplateConfigurationConstant.OUTPUT,MwTemplateConfigurationConstant.EXTEND);
        zabbixParam.put(MwTemplateConfigurationConstant.selectTags,MwTemplateConfigurationConstant.EXTEND);
        zabbixParam.put(MwTemplateConfigurationConstant.selectDependencies,MwTemplateConfigurationConstant.EXTEND);
        zabbixParam.put(MwTemplateConfigurationConstant.selectFunctions,MwTemplateConfigurationConstant.EXTEND);
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TRIGGER_GET, zabbixParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        List<TriggerParam> triggerParams = JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), TriggerParam.class);
        if(CollectionUtils.isEmpty(triggerParams)){return null;}
        for (TriggerParam triggerParam : triggerParams) {
            List<String> paramDependencies = triggerParam.getDependencies();
            if(CollectionUtils.isEmpty(paramDependencies)){continue;}
            List<TriggerParam> params = new ArrayList<>();
            for (String paramDependency : paramDependencies) {
                TriggerParam parseObject = JSONObject.parseObject(paramDependency, TriggerParam.class);
                params.add(parseObject);
            }
            triggerParam.setDependenciesData(params);
        }
        //翻译表达式
        translateExpressionBatch(triggerParams,param,1);
        return triggerParams.get(0);
    }
}
